package com.dkd.sbtz.controller;

import java.io.IOException;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.dkd.common.core.page.PageDomain;
import com.dkd.common.core.page.TableSupport;
import com.dkd.common.utils.PageUtils;
import com.dkd.common.utils.StringUtils;
import com.dkd.common.utils.sql.SqlUtil;
import com.dkd.sbtz.domain.ordervo.*;
import com.dkd.sbtz.domain.ordervo.exportsheet.*;
import org.apache.ibatis.type.Alias;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.dkd.common.annotation.Log;
import com.dkd.common.core.controller.BaseController;
import com.dkd.common.core.domain.AjaxResult;
import com.dkd.common.enums.BusinessType;
import com.dkd.sbtz.domain.AssetWorkOrder;
import com.dkd.sbtz.service.IAssetWorkOrderService;
import com.dkd.common.utils.poi.ExcelUtil;
import com.dkd.common.core.page.TableDataInfo;

/**
 * 工单列表Controller
 * 
 * @author xzj
 * @date 2025-09-09
 */
@Alias("AssetWorkOrder")
@RestController
@RequestMapping("/sbtz/order")
public class AssetWorkOrderController extends BaseController
{
    @Autowired
    private IAssetWorkOrderService assetWorkOrderService;






    /*最新可以正常使用，先注释*/
    @GetMapping("/list")
    public TableDataInfo list(AssetWorkOrder query) {
        // 若依原生 // 会读取前端 pageNum/pageSize/orderBy
        startPage();
        List<AssetWorkOrder> rows = assetWorkOrderService.selectPageAndFill(query);
        return getDataTable(rows);
    }






    /** 前端可能传 createTime / updateTime / woCode ...（驼峰） */
    private static final Map<String, String> ORDER_BY_WHITELIST;
    static {
        Map<String, String> m = new HashMap<>();
        m.put("createTime", "n.create_time");
        m.put("updateTime", "n.update_time");
        m.put("woCode",     "n.wo_code");
        m.put("woName",     "n.wo_name");
        m.put("urgency",    "n.urgency");
        m.put("status",     "n.status");
        m.put("priorityScore", "n.priority_score");
        // 兼容下划线写法（如果你的前端有可能直接传 DB 字段）
        m.put("create_time", "n.create_time");
        m.put("update_time", "n.update_time");
        m.put("wo_code",     "n.wo_code");
        m.put("wo_name",     "n.wo_name");
        ORDER_BY_WHITELIST = Collections.unmodifiableMap(m);
    }

    /**
     * 组装安全的 ORDER BY 子句；不在白名单内则返回空串（不排序）<br/>
     * 可支持多列：前端传 "createTime,woCode" 时，会依次生效。
     */
    private String buildSafeOrderBy(String orderByColumn, String isAsc) {
        if (StringUtils.isEmpty(orderByColumn)) {
            // 需要默认排序就返回，如默认按创建时间倒序：
            // return "n.create_time desc";
            return "";
        }

        // 支持多列逗号分隔
        String dir = "desc".equalsIgnoreCase(isAsc) ? "DESC" : "ASC";
        String[] cols = orderByColumn.split(",");

        List<String> fragments = new ArrayList<>();
        for (String raw : cols) {
            String key = raw == null ? "" : raw.trim();
            if (key.isEmpty()) continue;
            String col = ORDER_BY_WHITELIST.get(key);
            if (col != null) {
                fragments.add(col + " " + dir);
            }
        }
        // 全不合法则不排序
        if (fragments.isEmpty()) return "";
        // 多列拼接
        return String.join(", ", fragments);
    }






//    private String buildSafeOrderBy(String col, String dir) {
//        col = SqlUtil.escapeOrderBySql(col);
//        Map<String,String> map = new HashMap<>();
//        // 前端列 prop  ->  数据库真实列（注意别名，与 XML 的 FROM 别名要一致）
//        map.put("createTime", "n.create_time");
//        map.put("updateTime", "n.update_time");
//        map.put("name",       "n.name");
//        map.put("code",       "n.code");
//        map.put("id",         "n.id");
//
//        String safeCol = map.getOrDefault(col, "n.create_time");
//        String safeDir = "asc".equalsIgnoreCase(dir) ? "asc" : "desc";
//        return safeCol + " " + safeDir + ", n.id " + safeDir; // 稳定次序
//    }


//    @PreAuthorize("@ss.hasPermi('sbtz:order:list')")
    @GetMapping("/nodeid/{id}")
    public TableDataInfo getOrderByNodeId(@PathVariable("id") Long id) {
        startPage(); // ★ 必须先调用
        List<ListNodeAndSpare> list = assetWorkOrderService.selectByNodeId(id);
        return getDataTable(list);
    }


    /**
     * 导出工单列表列表
     */
//    @PreAuthorize("@ss.hasPermi('sbtz:order:export')")
//    @Log(title = "工单列表", businessType = BusinessType.EXPORT)
//    @PostMapping("/export")
//    public void export(HttpServletResponse response, AssetWorkOrder assetWorkOrder)
//    {
//        List<AssetWorkOrder> list = assetWorkOrderService.selectAssetWorkOrderList(assetWorkOrder);
//        ExcelUtil<AssetWorkOrder> util = new ExcelUtil<AssetWorkOrder>(AssetWorkOrder.class);
//        util.exportExcel(response, list, "工单列表数据");
//    }


//    @PreAuthorize("@ss.hasPermi('asset:order:export')")
//    @GetMapping("/export")
//    public void export(AssetWorkOrder q, HttpServletResponse response) {
//        List<WorkOrderExportVO> list = assetWorkOrderService.selectForExport(q);
//        ExcelUtil<WorkOrderExportVO> util = new ExcelUtil<>(WorkOrderExportVO.class);
//        util.exportExcel(response, list, "工单导出");
//    }

    // src/main/java/com/dkd/sbtz/controller/AssetWorkOrderController.java
    @PreAuthorize("@ss.hasPermi('sbtz:order:exportFull')")
    @Log(title = "工单完整信息", businessType = BusinessType.EXPORT)
    @RequestMapping(value = "/exportFull", method = {RequestMethod.GET, RequestMethod.POST})
    public void exportFull(HttpServletResponse response, AssetWorkOrder query) {
        // 这里 AssetWorkOrder 会自动绑定 GET 的 queryString 或 POST 的 form 表单参数
        doExport(response, query);
    }

    // 如果你的前端 POST 发的是 JSON（application/json），再补一个：
    @PreAuthorize("@ss.hasPermi('sbtz:order:exportFull')")
    @Log(title = "工单完整信息", businessType = BusinessType.EXPORT)
    @PostMapping(value = "/exportFull", consumes = "application/json")
    public void exportFullJson(HttpServletResponse response, @RequestBody AssetWorkOrder query) {
        doExport(response, query);
    }

    private void doExport(HttpServletResponse response, AssetWorkOrder query) {
        List<AssetWorkOrder> rows = assetWorkOrderService.selectForExport(query);  // 复用你已有的 selectPageAndFill
        List<OrderFullExportVo> vos = assetWorkOrderService.buildFullExportVo(rows);
        new com.dkd.common.utils.poi.ExcelUtil<>(OrderFullExportVo.class)
                .exportExcel(response, vos, "工单完整信息");
    }

    /**
     * 获取工单列表详细信息
     */
//    @PreAuthorize("@ss.hasPermi('sbtz:order:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(assetWorkOrderService.selectAssetWorkOrderById(id));
    }

    /**
     * 新增工单列表
     */
//    @PreAuthorize("@ss.hasPermi('sbtz:order:add')")
//    @Log(title = "工单列表", businessType = BusinessType.INSERT)
//    @PostMapping
//    public AjaxResult add(@RequestBody AssetWorkOrder assetWorkOrder)
//    {
//        int result = assetWorkOrderService.insertAssetWorkOrder(assetWorkOrder);
//        if (result > 0) {
//            // 返回包含ID的成功响应
//            return AjaxResult.success("新增成功", assetWorkOrder.getId());
//        }
//        return AjaxResult.error("新增失败");
//    }

    /**
     * 修改工单列表
     */


    /**
     * 删除工单列表
     */
//    @PreAuthorize("@ss.hasPermi('sbtz:order:remove')")
    @Log(title = "工单列表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(assetWorkOrderService.deleteAssetWorkOrderByIds(ids));
    }



    /*工单报表echarts相关*/
    @GetMapping("/status")
    public AjaxResult status(String beginTime, String endTime) {
        return AjaxResult.success(assetWorkOrderService.statusReport(beginTime, endTime));
    }
    @GetMapping("/type")
    public AjaxResult type(String beginTime, String endTime) {
        return AjaxResult.success(assetWorkOrderService.typeReport(beginTime, endTime));
    }
    /*工单报表echarts相关完毕*/



    /*工单 备件一起添加*/
    /** 新增（一次性提交：主表 + 备件清单） */
    @PostMapping
    public AjaxResult add(@RequestBody AssetWorkOrder req) {
        Long id = assetWorkOrderService.createWithSpares(req);
        return success(Map.of("id", id));
    }

    /** 修改（一次性提交：主表 + 备件清单；replaceSpares=true 时全量替换） */
    @PutMapping
    public AjaxResult edit(@RequestBody AssetWorkOrder req) {
        assetWorkOrderService.updateWithSpares(req);
        return success();
    }

    /** 如你更偏好 RESTful 路径，也可以加这个（前端用 PUT /sbtz/order/{id}） */
    @PutMapping("/{id}")
    public AjaxResult editById(@PathVariable Long id, @RequestBody AssetWorkOrder req) {
        req.setId(id);
        assetWorkOrderService.updateWithSpares(req);
        return success();
    }
    /*工单 备件一起添加完毕*/



    @GetMapping("/history")
    public TableDataInfo history(OrderSpareHistoryQuery q) {
        // 不再调用 BaseController.startPage()，避免把分页绑定到第二段详情查询上
        return assetWorkOrderService.selectOrderSpareHistory(q);
    }



    /*多 sheet 导出*/
    // src/main/java/com/dkd/sbtz/controller/AssetWorkOrderController.java
    @PreAuthorize("@ss.hasPermi('sbtz:order:exportFull')")
    @Log(title = "工单完整信息(多Sheet)", businessType = BusinessType.EXPORT)
    @RequestMapping(value = "/exportFullXlsx", method = {RequestMethod.GET, RequestMethod.POST})
    public void exportFullXlsx(HttpServletResponse response, AssetWorkOrder query) throws IOException {
        doExportFullXlsx(response, query);
    }

    @PreAuthorize("@ss.hasPermi('sbtz:order:exportFull')")
    @Log(title = "工单完整信息(多Sheet)", businessType = BusinessType.EXPORT)
    @PostMapping(value = "/exportFullXlsx", consumes = "application/json")
    public void exportFullXlsxJson(HttpServletResponse response, @RequestBody AssetWorkOrder query) throws IOException {
        doExportFullXlsx(response, query);
    }

    private void doExportFullXlsx(HttpServletResponse response, AssetWorkOrder query) throws IOException {
        // 不分页拉全量 + 回填 node/attachments/spares（你已有）
        List<AssetWorkOrder> orders = assetWorkOrderService.selectForExport(query);

        // 拍扁成三份
        List<OrderMainRow> mainRows   = ExportAssembler.toMainRows(orders);
        List<OrderAttachmentRow> att  = ExportAssembler.toAttachmentRows(orders);
        List<OrderSpareRow> spare     = ExportAssembler.toSpareRows(orders);

        // 文件名
        String fileName = "工单完整信息_" + java.time.LocalDate.now() + ".xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition",
                "attachment; filename=" + java.net.URLEncoder.encode(fileName, java.nio.charset.StandardCharsets.UTF_8));

        // 多 Sheet 流式写
        try (org.apache.poi.xssf.streaming.SXSSFWorkbook wb = new org.apache.poi.xssf.streaming.SXSSFWorkbook(200)) {
            ExcelSheets.writeSheet(
                    wb, "工单",
                    OrderMainRow.HEADERS,
                    mainRows,
                    ExportAssembler::fillMainRow
            );
            ExcelSheets.writeSheet(
                    wb, "附件",
                    OrderAttachmentRow.HEADERS,
                    att,
                    ExportAssembler::fillAttachmentRow
            );
            ExcelSheets.writeSheet(
                    wb, "备件",
                    OrderSpareRow.HEADERS,
                    spare,
                    ExportAssembler::fillSpareRow
            );

            wb.write(response.getOutputStream());
            // SXSSF 临时文件清理
            wb.dispose();
        }
    }



}
